home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / tkern10.zip / SRC\STDIO.C < prev    next >
Text File  |  1994-07-09  |  8KB  |  535 lines

  1. /*
  2.  *  This file forms part of "TKERN" - "Troy's Kernel for Windows".
  3.  *
  4.  *  Copyright (C) 1994  Troy Rollo <troy@cbme.unsw.EDU.AU>
  5.  *
  6.  *  This file is explicitly placed in the public domain. You may use it
  7.  *  it for any purpose you see fit, including, but not limited to,
  8.  *  incorperating it into a private, commercial, public domain,
  9.  *  shareware, freeware or free software work.
  10.  */
  11.  
  12. #include <windows.h>
  13.  
  14. #include <stdio.h>
  15. #include <fcntl.h>
  16. #include <io.h>
  17. #include <stdarg.h>
  18. #include <stdlib.h>
  19. #include <memory.h>
  20.  
  21. int
  22. __formatter(    int    (*func)(void *a, char b),
  23.         void    *func_arg,
  24.         char    const *format,
  25.         va_list    arg);
  26.  
  27. #define    MAXFILES 20
  28. #define    BUFSIZ    2048
  29.  
  30. FILE    _iob[MAXFILES];
  31.  
  32.  
  33. static    int getmodes(char const *mode,
  34.             int *flags)
  35. {
  36.     int    plus = 0;
  37.     int    reading = 0;
  38.     int    writing = 0;
  39.     int    binary = 0;
  40.     int    appending = 0;
  41.     int    modes;
  42.  
  43.     *flags = 0;
  44.  
  45.     while (*mode)
  46.     {
  47.         switch(*mode++)
  48.         {
  49.         case 'w':
  50.             writing = 1;
  51.             break;
  52.  
  53.         case 'r':
  54.             reading = 1;
  55.             break;
  56.  
  57.         case 'a':
  58.             appending = 1;
  59.             break;
  60.  
  61.         case 'b':
  62.             binary = 1;
  63.             break;
  64.  
  65.         case 't':
  66.             binary = 0;
  67.             break;
  68.  
  69.         case '+':
  70.             plus = 1;
  71.             break;
  72.         }
  73.     }
  74.  
  75.     if (writing)
  76.     {
  77.         if (plus || reading)
  78.         {
  79.             *flags = __FL_READ | __FL_WRITE;
  80.             modes = O_RDWR | O_CREAT | O_TRUNC;
  81.         }
  82.         else
  83.         {
  84.             *flags = __FL_WRITE;
  85.             modes = O_WRONLY | O_CREAT | O_TRUNC;
  86.         }
  87.     }
  88.     else if (appending)
  89.     {
  90.         if (plus || reading)
  91.         {
  92.             *flags = __FL_READ | __FL_WRITE;
  93.             modes = O_RDWR | O_CREAT;
  94.         }
  95.         else
  96.         {
  97.             *flags = __FL_WRITE;
  98.             modes = O_WRONLY | O_CREAT;
  99.         }
  100.     }
  101.     else if (reading)
  102.     {
  103.         if (plus)
  104.         {
  105.             *flags = __FL_READ | __FL_WRITE;
  106.             modes = O_RDWR;
  107.         }
  108.         else
  109.         {
  110.             *flags = __FL_READ;
  111.             modes = O_RDONLY;
  112.         }
  113.     }
  114.     if (binary)
  115.         modes |= O_BINARY;
  116.     else
  117.         modes |= O_TEXT;
  118.  
  119.     return    modes;
  120. }
  121.  
  122. static    void    _flsbuf(FILE *fp)
  123. {
  124.     if (fp->flags & __FL_MODIFIED)
  125.     {
  126.         lseek(fp->fd, -fp->readsize, 1);
  127.         write(fp->fd, fp->buffer, fp->bufsize);
  128.         fp->flags &= ~__FL_MODIFIED;
  129.     }
  130. }
  131.  
  132. static    int    _filbuf(FILE *fp)
  133. {
  134.     _flsbuf(fp);
  135.     if (fp->flags & __FL_READ)
  136.         fp->bufsize = read(fp->fd, fp->buffer, BUFSIZ);
  137.     else
  138.         fp->bufsize = 0;
  139.     if (!fp->bufsize)
  140.     {
  141.         fp->flags |= __FL_EOF;
  142.     }
  143.     else if (fp->bufsize == -1)
  144.     {
  145.         fp->bufsize= 0;
  146.         fp->flags |= __FL_ERROR;
  147.         fp->readsize = 0;
  148.     }
  149.     else
  150.     {
  151.         fp->flags &= ~(__FL_ERROR | __FL_EOF);
  152.         fp->readsize = fp->bufsize;
  153.     }
  154.     fp->bufidx = 0;
  155.     return fp->bufsize;
  156. }
  157.  
  158. FILE    *fopen(char const *name, char const *mode)
  159. {
  160.     int    fd;
  161.     FILE    *fp;
  162.     int    modes;
  163.     int    flags;
  164.  
  165.     modes = getmodes(mode, &flags);
  166.  
  167.     fd = open(name, modes, 0666);
  168.  
  169.     if (fd == -1)
  170.         return 0;
  171.  
  172.     return fdopen(fd, mode);
  173. }
  174.  
  175. FILE    *fdopen(int fd, char const *mode)
  176. {
  177.     int    modes;
  178.     FILE    *fp;
  179.     int    flags;
  180.  
  181.     modes = getmodes(mode, &flags);
  182.     fp = &_iob[fd];
  183.     fp->fd = fd;
  184.     fp->modes = modes;
  185.     fp->flags = flags;
  186.     if (fp->buffer)
  187.     {
  188.         free(fp->buffer);
  189.         fp->buffer = 0;
  190.         fp->bufsize = 0;
  191.         fp->bufidx = 0;
  192.     }
  193.     if (!isatty(fd))
  194.     {
  195.         fp->buffer = (char *) malloc(BUFSIZ);
  196.         fp->bufsize = BUFSIZ;
  197.         fp->bufidx = BUFSIZ;
  198.         _filbuf(fp);
  199.     }
  200.  
  201.     return fp;
  202. }
  203.  
  204.  
  205. int    fclose(FILE *fp)
  206. {
  207.     _flsbuf(fp);
  208.     close(fp->fd);
  209.     if (fp->buffer)
  210.     {
  211.         free(fp->buffer);
  212.         fp->bufsize = 0;
  213.         fp->bufidx = 0;
  214.         fp->buffer = 0;
  215.     }
  216.     fp->fd = -1;
  217.     fp->flags = 0;
  218.     fp->modes = 0;
  219.     return 0;
  220. }
  221.  
  222. void    _init_all_files(void)
  223. {
  224.     int    i;
  225.  
  226.     for (i = 0; i < MAXFILES; i++)
  227.         _iob[i].fd = -1;
  228. }
  229.  
  230. void    _close_all_files(void)
  231. {
  232.     int    fd;
  233.  
  234.     for (fd = 0; fd < MAXFILES; fd++)
  235.     {
  236.         if (_iob[fd].fd != -1)
  237.         {
  238.             fclose(&_iob[fd]);
  239.         }
  240.     }
  241. }
  242.  
  243. FILE    *freopen(char const *file, char const *mode, FILE *fp)
  244. {
  245.     FILE    *fpNew;
  246.  
  247.     if (fp->fd != -1)
  248.         fclose(fp);
  249.     fpNew = fopen(file, mode);
  250.     if (!fpNew)
  251.         return 0;
  252.     if (fp == fpNew)
  253.         return fp;
  254.     dup2(fpNew->fd, fp - _iob);
  255.     fclose(fpNew);
  256.     return fdopen(fp - _iob, mode);
  257. }
  258.  
  259.  
  260.  
  261. int    ungetc(char c, FILE *fp)
  262. {
  263.     if (fp->flags & __FL_UNGET)
  264.         return EOF;
  265.     fp->flags |= __FL_UNGET;
  266.     fp->ungetchar = c;
  267.     return 0;
  268. }
  269.  
  270. int    getc(FILE *fp)
  271. {
  272.     char    c;
  273.  
  274.     if (fp->flags & __FL_UNGET)
  275.     {
  276.         fp->flags &= ~__FL_UNGET;
  277.         return (unsigned) (unsigned char) fp->ungetchar;
  278.     }
  279.     else if (fp->buffer)
  280.     {
  281.         if (fp->bufidx < fp->bufsize)
  282.             return (unsigned) (unsigned char) (fp->buffer[fp->bufidx++]);
  283.         else if (_filbuf(fp))
  284.             return (unsigned) (unsigned char) fp->buffer[fp->bufidx++];
  285.         else
  286.             return EOF;
  287.     }
  288.     else if (read(fp->fd, &c, 1) == 1)
  289.         return (unsigned) (unsigned char) c;
  290.     else
  291.         return EOF;
  292. }
  293.  
  294. int    putc(char c, FILE *fp)
  295. {
  296.     if (fp->buffer)
  297.     {
  298.         if (fp->bufidx < BUFSIZ)
  299.         {
  300.             fp->buffer[fp->bufidx++] = c;
  301.             if (fp->bufidx > fp->bufsize)
  302.                 fp->bufsize = fp->bufidx;
  303.         }
  304.         else
  305.         {
  306.             _filbuf(fp);
  307.             fp->buffer[fp->bufidx++] = c;
  308.         }
  309.         fp->flags |= __FL_MODIFIED;
  310.         return c;
  311.     }
  312.     else
  313.     {
  314.         if (write(fp->fd, &c, 1) == 1)
  315.             return c;
  316.         else
  317.             return EOF;
  318.     }
  319. }
  320.  
  321. int    fscanf(FILE *fp, char const *format, ...)
  322. {
  323.     va_list    args;
  324.     int    retval;
  325.  
  326.     va_start(args, format);
  327.     retval = vfscanf(fp, format, args);
  328.     va_end(args);
  329.     return retval;
  330. }
  331. int    scanf(char const *format, ...)
  332. {
  333.     va_list    args;
  334.     int    retval;
  335.  
  336.     va_start(args, format);
  337.     retval = vfscanf(stdin, format, args);
  338.     va_end(args);
  339.     return retval;
  340. }
  341.  
  342. int    fp_fmtout(void *pv, char c)
  343. {
  344.     FILE *fp = (FILE *) pv;
  345.  
  346.     putc(c, fp);
  347.     return 1;
  348. }
  349.  
  350. int    vfprintf(FILE *fp, char const *format, va_list arg)
  351. {
  352.     return __formatter(fp_fmtout, fp, format, arg);
  353. }
  354.  
  355. int    fprintf(FILE *fp, char const *format, ...)
  356. {
  357.     va_list    args;
  358.     int    retval;
  359.  
  360.     va_start(args, format);
  361.     retval = vfprintf(fp, format, args);
  362.     va_end(args);
  363.     return retval;
  364. }
  365.  
  366. int    printf(char const *format, ...)
  367. {
  368.     va_list    args;
  369.     int    retval;
  370.  
  371.     va_start(args, format);
  372.     retval = vfprintf(stdout, format, args);
  373.     va_end(args);
  374.     return retval;
  375. }
  376.  
  377. int    puts(char const *pch)
  378. {
  379.     while (*pch)
  380.         if (putchar(*pch) == EOF)
  381.             return EOF;
  382.         else
  383.             pch++;
  384.     if (putchar('\n') == EOF)
  385.         return EOF;
  386.     return 0;
  387. }
  388.  
  389. char    *gets(char *pch)
  390. {
  391.     char    c;
  392.     char    *pchOut = pch;
  393.  
  394.     while (1)
  395.     {
  396.         c = getchar();
  397.         if (c == EOF)
  398.             return 0;
  399.         if (c == '\n')
  400.         {
  401.             *pchOut = '\0';
  402.             return pch;
  403.         }
  404.         *pchOut++ = c;
  405.     }
  406. }
  407.  
  408. int    fputs(char const *pch, FILE *fp)
  409. {
  410.     while (*pch)
  411.         if (putc(*pch, fp) == EOF)
  412.             return EOF;
  413.         else
  414.             pch++;
  415.     return 0;
  416. }
  417.  
  418. char    *fgets(char *pch, int nMax, FILE *fp)
  419. {
  420.     char    c;
  421.     char    *pchOut = pch;
  422.  
  423.     while (--nMax)
  424.     {
  425.         c = getc(fp);
  426.         if (c == EOF)
  427.             return 0;
  428.         *pchOut++ = c;
  429.         if (c == '\n')
  430.             break;
  431.     }
  432.     *pchOut = '\0';
  433.     return pch;
  434. }
  435.  
  436.  
  437. int
  438. fread(    char    *pchBuffer,
  439.     int    nSize,
  440.     int    nCount,
  441.     FILE    *fp)
  442. {
  443.     int    nRead = 0;
  444.     int    nReadSize = nSize * nCount;
  445.     int    nNow;
  446.  
  447.     if (nReadSize == 0)
  448.         return 0;
  449.     if (fp->flags & __FL_UNGET)
  450.     {
  451.         fp->flags &= ~__FL_UNGET;
  452.         *pchBuffer++ = fp->ungetchar;
  453.         nRead++;
  454.     }
  455.     if (fp->buffer)
  456.     {
  457.         while (nRead < nReadSize)
  458.         {
  459.             if (nReadSize - nRead < fp->bufsize - fp->bufidx)
  460.                 nNow = nReadSize - nRead;
  461.             else
  462.                 nNow = fp->bufsize - fp->bufidx;
  463.  
  464.             if (nNow)
  465.             {
  466.                 memcpy(pchBuffer, fp->buffer + fp->bufidx, nNow);
  467.                 fp->bufidx += nNow;
  468.                 pchBuffer += nNow;
  469.                 nRead += nNow;
  470.             }
  471.             else if (!_filbuf(fp))
  472.             {
  473.                 return nRead / nSize;
  474.             }
  475.         }
  476.         return nCount;
  477.     }
  478.     else
  479.     {
  480.         nRead = read(fp->fd, pchBuffer, nReadSize);
  481.         if (nRead <= -1)
  482.             return EOF;
  483.         return nRead / nSize;
  484.     }
  485. }
  486.  
  487. int
  488. fwrite(    char    const *pchBuffer,
  489.     int    nSize,
  490.     int    nCount,
  491.     FILE    *fp)
  492. {
  493.     int    nWritten = 0;
  494.     int    nToWrite = nSize * nCount;
  495.     int    nNow;
  496.  
  497.     if (fp->buffer)
  498.     {
  499.         while (nWritten < nToWrite)
  500.         {
  501.             if (BUFSIZ - fp->bufidx < nToWrite - nWritten)
  502.                 nNow = BUFSIZ - fp->bufidx;
  503.             else
  504.                 nNow = nToWrite - nWritten;
  505.             if (nNow)
  506.             {
  507.                 memcpy(fp->buffer + fp->bufidx, pchBuffer, nNow);
  508.                 pchBuffer += nNow;
  509.                 fp->bufidx += nNow;
  510.                 nWritten += nNow;
  511.                 if (fp->bufidx > fp->bufsize)
  512.                     fp->bufsize = fp->bufidx;
  513.                 fp->flags |= __FL_MODIFIED;
  514.             }
  515.             else
  516.             {
  517.                 _filbuf(fp);
  518.             }
  519.         }
  520.         return nWritten / nSize;
  521.     }
  522.     else
  523.     {
  524.         nWritten = write(fp->fd, (void *) pchBuffer, nToWrite);
  525.         if (nWritten < 0)
  526.             return EOF;
  527.         return nWritten / nSize;
  528.     }
  529. }
  530.  
  531. int    ferror(FILE *fp)
  532. {
  533.     return (fp->flags & __FL_ERROR) ? 1 : 0;
  534. }
  535.